"""
    服务器端逻辑处理模块
"""
import pymysql
from socket import *
from select import *
class Controller:
    def __init__(self):#开启epoll io多路服用
        self.s = socket()
        self.s.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)
        self.s.bind(('0.0.0.0', 7977))
        self.s.listen(5)
        # 创建eｐｏｌｌ对象
        self.ep = epoll()
        # 　建立查找字典，通过ＩＯ的fileno查找io对象
        # 　始终与ｒｅｇｉｓｔｅｒ的ＩＯ保持一直
        self.fdmap = {self.s.fileno(): self.s}
        # 　关注　ｓ
        self.ep.register(self.s, EPOLLIN)
        self.db = pymysql.connect(host='localhost',
                             port=3306,
                             user='root',
                             password='zhy230604.',
                             database='words',
                             charset='utf8')
        self.cur = self.db.cursor()
    def start(self):
        while True:
            events = self.ep.poll()  # 阻塞等待ＩＯ发生
            print("你有新的ＩＯ需要处理哦")
            # 　循环遍历查看哪个ＩＯ准备就绪
            for fd, event in events:
                print(events)
                if fd == self.s.fileno():
                    c, addr = self.fdmap[fd].accept()
                    print("Connect from", addr)
                    # 　关注客户端连接套接字
                    self.ep.register(c, EPOLLIN | EPOLLET)  # 设置边缘触发
                    self.fdmap[c.fileno()] = c  # 维护字典
                elif event & EPOLLIN:
                    data = self.fdmap[fd].recv(1024).decode()
                    print(data)
                    if not data:
                        self.ep.unregister(fd) #　取消监控
                        self.fdmap[fd].close()
                        del self.fdmap[fd] #　从字典删除
                        continue
                    self.handle(self.fdmap[fd],data)#消息处理函数
                #     self.ep.unregister(fd) # 先取消关注再重新添加
                #     self.ep.register(self.fdmap[fd], EPOLLOUT)
                # elif event & POLLOUT:
                #     self.fdmap[fd].send(b'OK')
                #     self.ep.unregister(fd)
                #     self.ep.register(self.fdmap[fd], EPOLLIN)
    def register_s(self,username, password, comment):
        sql = "select * from user where username='%s'" % username
        self.cur.execute(sql)
        str = self.cur.fetchone()
        if not str:
            try:
                sql = "insert into user (username,password,comment) values (%s,%s,%s)"
                self.cur.execute(sql, [username, password,comment])
                self.db.commit()
            except Exception as e:
                self.db.rollback()
                return e
            print('insert user:',username)
            return 'ok'
        return 'username exist'
    def longin(self,username, password):
        sql = "select * from user where username='%s' and password='%s'" % (username,password)
        self.cur.execute(sql)
        str = self.cur.fetchone()
        if not str:
            return 'username or password error!'
        return 'ok'
    def query(self,user,word):
        sql = "select explains from words where word='%s'" % (word)
        self.cur.execute(sql)
        str = self.cur.fetchone()
        if not str:
            return 'word error!'
        try:
            sql = "insert into record (username,word) values (%s,%s)"
            self.cur.execute(sql, [user, word])
            self.db.commit()
        except Exception as e:
            self.db.rollback()
        return str[0]
    def record(self,username):
        sql = "select * from record where username='%s' limit 10" % (username)
        self.cur.execute(sql)
        tuple_str = self.cur.fetchall()
        if not tuple_str:
            return 'record error!'
        str_re = ''
        for i in tuple_str:
            str_re += str(i) + '\n'
        return str_re
    def handle(self,c, data):#按协议解析处理消息
        list_str = data.split(' ')
        print(list_str)
        if list_str[0] == 'R':
            re = self.register_s(list_str[1],list_str[2],list_str[3])
        elif list_str[0] == 'L':
            re = self.longin(list_str[1],list_str[2])
        elif list_str[0] == 'W':
            re = self.query(list_str[1],list_str[2])
        elif list_str[0] == 'J':
            re = self.record(list_str[1])
        else:
            re = 'request error!'
        c.send(re.encode())


if __name__ == '__main__':
    c = Controller()
    c.start()